#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>

using namespace std;

static void showPending(sigset_t &pending)
{
    for (int sig = 1; sig <= 31; sig++)
    {
        if (sigismember(&pending, sig)) cout << " 1";
        else cout << " 0";
    }
    cout << endl;
}

static void blockSig(int signum)
{
    sigset_t bset;
    
    sigemptyset(&bset);

    sigaddset(&bset, signum);
    
    int n = sigprocmask(SIG_BLOCK, &bset, nullptr);
    assert(n != -1);
    (void)n;
    cout << "阻塞 " << signum << " 号信号成功, pid: " << getpid() << endl; 
}

// int main()
// {
//     // 屏蔽所有信号
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         blockSig(sig);
//     }

//     sigset_t pending;
//     sigemptyset(&pending);
//     while (true)
//     {
//         showPending(pending);
//         sleep(1);
//     }

//     return 0;
// }

void catchSig(int signum)
{
    cout << "获得信号：" << signum << endl;
}

int main()
{
    signal(2, catchSig);

    // 1.定义信号集
    sigset_t bset, obset; // 信号屏蔽字,阻塞信号集
    sigset_t pending; // 信号集

    // 2.初始化信号集
    sigemptyset(&bset);
    sigemptyset(&obset);
    sigemptyset(&pending);

    // 3.添加进行屏蔽的信号
    sigaddset(&bset, 2); // SIGINT

    // 4.设置到内核中
    int n = sigprocmask(SIG_BLOCK, &bset, &obset);
    assert(n != -1);
    (void)n;
    cout << "阻塞2号信号成功, pid: " << getpid() << endl;  

    // 5.重复打印pending信号集
    int count = 0;
    while (true)
    {
        // 5.1 获取进程的pending信号集
        sigpending(&pending);

        // 5.2 显示pending信号集中没有被递达的信号
        showPending(pending);
        sleep(1);
        count++;

        if (count == 10)
        {
            cout << "解除阻塞2号信号" << endl;
            sigprocmask(SIG_SETMASK, &obset, nullptr); // 使用修改之前的信号集
        }
    }
    return 0;
}

// void catchSig(int signum)
// {
//     cout << "获得信号：" << signum << endl;
// }

// int main()
// { 
//     for (int i = 1; i <= 31; i++) signal(i, catchSig);

//     while (true) sleep(1);

//     return 0;
// }